package com.zr.service.car.impl;

import com.zr.dao.base.BaseDriverDao;
import com.zr.dao.car.CarInfoDao;
import com.zr.dao.car.CarPhotoDao;
import com.zr.dao.dispatch.DispatchTicketDao;
import com.zr.exception.BusinessException;
import com.zr.service.car.CarService;
import com.zr.vo.base.BaseDriver;
import com.zr.vo.car.CarInfo;
import com.zr.vo.car.CarPhoto;
import com.zr.vo.dispatch.DispatchTicket;
import com.zr.vo.sys.SysUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 车辆管理业务层方法实现类
 *
 * @author 王鑫
 * @date 2022/10/30
 */
@Service
public class CarServiceImpl implements CarService {
    @Value("${img.path}")
    private String imgPath;
    @Resource
    private CarInfoDao carInfoDao;
    @Resource
    private CarPhotoDao carPhotoDao;
    @Resource
    private DispatchTicketDao dispatchTicketDao;
    @Resource
    private BaseDriverDao baseDriverDao;

    /**
     * 条件查询车辆信息列表，带分页
     *
     * @param carInfo
     * @return List<CarInfo>
     */
    @Override
    public List<CarInfo> list(CarInfo carInfo) {
        return carInfoDao.selectByCondition(carInfo);
    }

    /**
     * 查询所有车辆
     *
     * @return List<CarInfo>
     */
    @Override
    public List<CarInfo> listAll() {
        return carInfoDao.selectAll();
    }

    /**
     * 新增车辆
     *
     * @param carInfo
     * @return int
     */
    @Override
    public int add(CarInfo carInfo) {
        //如果新增时关联了司机,修改司机状态
        if (carInfo.getBaseDriver() != null) {
            BaseDriver baseDriver = new BaseDriver();
            baseDriver.setDriverId(carInfo.getBaseDriver().getDriverId());
            baseDriver.setStatus("1");
            baseDriverDao.updateByDriverIdSelective(baseDriver);
//            避免未选司机时空指针
            carInfo.setAnotherOne(carInfo.getBaseDriver().getDriverName());
            carInfo.setDriverId(carInfo.getBaseDriver().getDriverId());
        }
        carInfo.setCarStatus("空闲");
        carInfo.setCreateTime(new Date());
        carInfo.setLocation("宁波");
        return carInfoDao.insertSelective(carInfo);
    }

    /**
     * 编辑车辆基础信息
     *
     * @param carInfo
     * @return int
     */
    @Transactional
    @Override
    public int edit(CarInfo carInfo) throws BusinessException {

        //判断前端是否传入了司机信息
        BaseDriver inputDriver = carInfo.getBaseDriver();
        if (inputDriver != null) {
            //修改旧司机的状态为空闲0
            BaseDriver oldDriver = new BaseDriver();
            oldDriver.setDriverId(carInfo.getDriverId());
            oldDriver.setStatus("0");
            baseDriverDao.updateByDriverIdSelective(oldDriver);

            BaseDriver newDriver = new BaseDriver();
            //关联司机后修改新司机状态 1
            newDriver.setDriverId(carInfo.getBaseDriver().getDriverId());
            newDriver.setStatus("1");
            baseDriverDao.updateByDriverIdSelective(newDriver);
            //更新车辆表司机属性
            carInfo.setDriverId(carInfo.getBaseDriver().getDriverId());
            carInfo.setAnotherOne(carInfo.getBaseDriver().getDriverName());
        }
        carInfo.setModifyTime(new Date());
        return carInfoDao.updateByPrimaryKeySelective(carInfo);
    }

    /**
     * 删除车辆
     *
     * @param id
     * @return int
     */
    @Override
    public int remove(Integer id) throws BusinessException {
        //判断车辆的状态，空闲才能删除
        CarInfo carInfo = carInfoDao.selectByPrimaryKey(id);

        if (!"空闲".equals(carInfo.getCarStatus())) throw new BusinessException("必须等待车辆完成调度单后，车辆空闲状态才可删除");
        //删除车辆照片
        carPhotoDao.deleteByNumber(carInfo.getNumber());
        return carInfoDao.deleteByPrimaryKey(id);
    }

    /**
     * 设置车辆头像
     *
     * @param files,number
     * @return List<String>
     * @throws IOException
     */
    @Override
    @Transactional
    public List<String> setHeadImg(MultipartFile[] files, String number) throws IOException {
        ArrayList<String> imgList = new ArrayList<>();
        if (files.length == 0) return null;
        //删除原来的车辆的图片信息
        carPhotoDao.deleteByNumber(number);
        for (MultipartFile file : files) {
            String imgUrl = UUID.randomUUID().toString() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            file.transferTo(new File(imgPath + imgUrl));
            // 把图片地址insert到car_photo数据库1
            CarPhoto carPhoto = new CarPhoto();
            carPhoto.setCarPhotoAddress(imgPath + imgUrl);
            carPhoto.setNumber(number);
            carPhotoDao.insertSelective(carPhoto);
            imgList.add(imgUrl);

        }
        return imgList;
    }

    /**
     * 查询所有与车辆相关的信息，包含车辆，司机，调度单
     *
     * @return
     */
    @Override
    public HashMap<String, Object> getCarAndDriver(Integer id) {
        HashMap<String, Object> map = new HashMap<>();
        CarInfo carInfo = carInfoDao.selectByPrimaryKey(id);
        BaseDriver baseDriver = baseDriverDao.selectByDriverId(carInfo.getDriverId());
        map.put("car", carInfo);
        map.put("driver", baseDriver);
        List<String> carPhotoPathList = carPhotoDao.selectPhotosByNumber(carInfo.getNumber());
        ArrayList<String> res = new ArrayList<>();
        for (String path : carPhotoPathList) {
            String imgBase = getImgBase(path);
            res.add(imgBase);
        }
        map.put("photos", res);
        return map;
    }

    /**
     * 根据车牌号，查询车辆的调度单信息(含对应订单信息)
     *
     * @param dispatchTicket
     * @return List<DispatchTicket>
     * @throws IOException
     */
    @Override
    public List<DispatchTicket> getDispatch(DispatchTicket dispatchTicket) {

        return dispatchTicketDao.selectAllByCarNumberContainsOrder(dispatchTicket);
    }


    /***
     * 查询在途与空闲车辆数
     * @return
     */
    @Override
    public List<Map> getCarUsage() {
        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        Integer bussyNum = carInfoDao.getBussyNum();
        Integer freeNum = carInfoDao.getFreeNum();
        map1.put("name", "在途车辆");
        map1.put("value", bussyNum);
        map2.put("name", "空闲车辆");
        map2.put("value", freeNum);
        List<Map> mapList = new ArrayList<>();
        mapList.add(map1);
        mapList.add(map2);
        return mapList;
    }

    /**
     * 根据调度单id获取车辆信息
     *
     * @param carNumber
     * @return CarInfo
     */
    @Override
    public CarInfo getCarByNumber(String carNumber) {
        return carInfoDao.selectByCarNumber(carNumber);
    }


    /**
     * 将图片转换成Base64编码
     *
     * @param imgFile 待处理图片地址
     * @return
     */
    public static String getImgBase(String imgFile) {
        // 将图片文件转化为二进制流
        InputStream in = null;
        byte[] data = null;
        File file=new File(imgFile);
        if(!file.exists()){
            imgFile="D:\\Img\\a.jpg";
        }
        // 读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 图片头
        return Base64.getEncoder().encodeToString(data);
    }

    /**
     * 通过id获取车辆司机和货车信息
     *
     * @param id
     * @return
     */
    @Override
    public HashMap<String, Object> getDriverAndCar(Integer id) {
        HashMap<String, Object> map = new HashMap<>();
        CarInfo carInfo = carInfoDao.selectByPrimaryKey(id);
        BaseDriver baseDriver = baseDriverDao.selectByDriverId(carInfo.getDriverId());
        map.put("car", carInfo);
        map.put("driver", baseDriver);
        return map;
    }
}
